﻿using UnityEngine;
using System.Collections;

/*
    使用方法:
 
        1. 添加DownloadBind Prefab
        2. 连接ZipDownloader
  
    代码例子:
 
        zipDownloader.Download("http://192.168.1.128:9888/images/file.zip");
        zipDownloader.EventZipDownloadSuccess += OnZipDownloadSuccess;
        zipDownloader.EventZipDownloadFail += OnZipDownloadFail;

        private void OnZipDownloadSuccess()
        {
            Debug.Log("---- OnZipDownloadSuccess");
        }

        private void OnZipDownloadFail(int error)
        {
            Debug.Log("---- OnZipDownloadFail");
        } 
 
     [hint]暂时MultiDownloader和ZipDownloader不可同时使用 
 
 * [change] 2015/07/24 解压过程的控制从Downloader移到这里
 * [change] 2015/07/24 下载文件不是zip文件会报错
 * [change] 2015/07/23 增加解压进度条，使用Cortoutine实现
 * 
 * todo
 *   分块解压的支持
 *   断点续传?
*/

public enum ZipDownloaderError
{
    UnCompressError,
    DownloadError,
    NotAZipFile,
    UnknownError
}

public class ZipDownloader : MonoBehaviour {

    public int                      maxRetryCount = 3;
    public Downloader               downloader;
    private static MultiDownloder   _multiDownloader;
    private int                     retryCount;

    private UnCompress              unCompress = null;
    // error code
    public static int               ERROR_UNCOMPRESS = 0;
    public static int               ERROR_DOWNLOAD = 1;
    public static int               ERROR_UNKNOWN = 2;
    public static int               ERROR_FILE_NOT_ZIP = 3;

	// Use this for initialization
	void Start () {
	    
	}
	
	// Update is called once per frame
	void Update () {
	    
	}
    
    #region Public Methods

    // 下载
    public void Download(string url) {

        if (!url.Contains(".zip"))
        {
            if (EventZipDownloadFail != null)
            {
                EventZipDownloadFail(ZipDownloaderError.NotAZipFile);
            }
        }
        else
        {
            downloader.Download(url);
            downloader.EventDownloadSuccess += OnDownloadSuccess;
            downloader.EventDownloadFail += OnDownloadFail;
        }        
    }

    // 解压
    public void DoUnCompress()
    {
       StartCoroutine(UnCompressAction());
    }

    #endregion // Public Methods

    #region Private Methods

    private IEnumerator UnCompressAction()
    {
        string filename = downloader.DownloaderFileName;
        unCompress = new UnCompress(filename, Application.persistentDataPath);
        yield return StartCoroutine(ProcessProgress(unCompress));

        if (unCompress.CurState == UnCompress.State.Failed)
        {
            if (EventZipDownloadFail != null)
            {
                StartCoroutine(DelayToInvoke.InvokeNextFrame(() =>
                {
                    EventZipDownloadFail(ZipDownloaderError.UnCompressError);
                }));
            }

            Debug.Log("[Downloader] Unzip failed. ");
            yield break;
        }
        else
        {
            if (EventZipDownloadSuccess != null)
            {
                StartCoroutine(DelayToInvoke.InvokeNextFrame(() =>
                {
                    EventZipDownloadSuccess();
                }));
            }
        }
        unCompress = null;
        FileUtil.DeleteFile(filename);
    }

    IEnumerator ProcessProgress(UnCompress curProgress)
    {
        while (true)
        {
            curProgress.Update();

            if (unCompress != null && unCompress.CurState == UnCompress.State.Uncompleted)
            {
                if (EventZipDownloadProgress != null)
                {
                    EventZipDownloadProgress(unCompress.progress);
                }
            }

            if (curProgress.CurState != UnCompress.State.Uncompleted)
                yield break;
            yield return null;
        }
    }

    private void OnDownloadProgress(float value) {
        Debug.Log("-- OnDownloadProgress : " + value);
    }

    private void OnDownloadSuccess(string url) {
        Debug.Log("-- OnDownloadSucess ");
        retryCount = maxRetryCount;

        // ui show uncompress
        Debug.Log("[ZipDownloader] finish download " + url);
        DoUnCompress();
    }

    private void OnDownloadFail(string url) {
        Debug.Log("-- OnDownloadFail ");
        if (retryCount <= 0)
        {
            if (EventZipDownloadFail != null)
            {
                EventZipDownloadFail(ZipDownloaderError.DownloadError);
            }
        }
        else
        {
            downloader.Download(url);
            retryCount--;
        }
    }

    #endregion // Private Methods

    #region Outlet Methods

    public delegate void OnZipDownloadSucces();
    public delegate void OnZipDownloadFail(ZipDownloaderError error);
    public delegate void OnZipDownloadProgress(float progress);

    public event OnZipDownloadSucces EventZipDownloadSuccess;
    public event OnZipDownloadFail EventZipDownloadFail;
    public event OnZipDownloadProgress EventZipDownloadProgress;

    #endregion

}
